home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-06-13 | 15.4 KB | 627 lines | [TEXT/CWIE] |
- //===============================================================================
- //===============================================================================
- //
- // TestPickerUtil.c
- //
- // john calhoun 1997
- //
- //===============================================================================
- //===============================================================================
-
-
- #include <CMICCProfile.h>
- #include <ColorPicker.h>
- #include "TestPicker.h"
-
-
- #define MIN3(a,b,c) ( ((a)<(b)) ? (((a)<(c))?(a):(c)) : (((b)<(c))?(b):(c)) )
- #define MAX3(a,b,c) ( ((a)>(b)) ? (((a)>(c))?(a):(c)) : (((b)>(c))?(b):(c)) )
-
- #define colorC color->cmyk.cyan
- #define colorM color->cmyk.magenta
- #define colorY color->cmyk.yellow
- #define colorK color->cmyk.black
- #define colorR color->rgb.red
- #define colorG color->rgb.green
- #define colorB color->rgb.blue
-
- enum
- {
- cmICCReservedFlagsMask = 0x0000FFFF, /* these bits of the flags field are defined and reserved by ICC */
- cmEmbeddedMask = 0x00000001, /* if bit 0 is 0 then not embedded profile, if 1 then embedded profile */
- cmEmbeddedUseMask = 0x00000002, /* if bit 1 is 0 then ok to use anywhere, if 1 then ok to use as embedded profile only */
- cmCMSReservedFlagsMask = 0xFFFF0000, /* these bits of the flags field are defined and reserved by CMS vendor */
- cmQualityMask = 0x00030000, /* if bits 16-17 is 0 then normal, if 1 then draft, if 2 then best */
- cmInterpolationMask = 0x00040000, /* if bit 18 is 0 then interpolation, if 1 then lookup only */
- cmGamutCheckingMask = 0x00080000 /* if bit 19 is 0 then create gamut checking info, if 1 then no gamut checking info */
- };
-
- struct CMConcatProfileSet3
- {
- UInt16 keyIndex; // Zero-based.
- UInt16 count; // Min 1.
- CMProfileRef profileSet[3]; // Ordered from Source -> Proof -> Dest
- };
- typedef struct CMConcatProfileSet3 CMConcatProfileSet3;
-
-
- long GetColorSyncVersion (void);
-
-
- //===================================================================== Functions
- //--------------------------------------------------------------------- InitToolbox
-
- void InitToolbox (void)
- {
- MoreMasters();
- MaxApplZone();
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- FlushEvents (everyEvent, 0);
- InitCursor();
-
- GetDateTime((unsigned long *)&qd.randSeed);
- }
-
- //-------------------------------------------------------------- WhatsOurDepth
-
- short WhatsOurDepth (void)
- {
- GDHandle thisDevice;
- short thisDepth;
- char wasState;
-
- thisDepth = 0;
- thisDevice = GetMainDevice();
-
- if (thisDevice)
- {
- wasState = HGetState((Handle)thisDevice);
- HLock((Handle)thisDevice);
- thisDepth = (**(**thisDevice).gdPMap).pixelSize;
- HSetState((Handle)thisDevice, wasState);
- }
-
- return (thisDepth);
- }
-
-
- //--------------------------------------------------------------------- RandomInt
-
- short RandomInt (short range)
- {
- register long rawResult;
-
- rawResult = Random();
- if (rawResult < 0)
- rawResult = -rawResult;
- return ((rawResult * (long)range) >> 15);
- }
-
- //--------------------------------------------------------------------- OpenSimpleWindow
-
- void OpenSimpleWindow (void)
- {
- SetRect(&windowBounds, 0, 0, 608, 420);
- simpleWindow = (WindowRef)NewCWindow(nil, &windowBounds, "\pColor Picker Demo",
- true, noGrowDocProc,
- (GrafPort *)(-1L), false, 0L);
-
- MoveWindow(simpleWindow, 16, 40, true);
-
- SetPort(simpleWindow);
- }
-
- //--------------------------------------------------------------------- AddMenusToMenuBar
-
- void AddMenusToMenuBar (void)
- {
- appleMenu = GetMenu(128);
- AppendResMenu(appleMenu, 'DRVR');
- InsertMenu(appleMenu, 0);
-
- fileMenu = GetMenu(129);
- InsertMenu(fileMenu, 0);
-
- editMenu = GetMenu(130);
- InsertMenu(editMenu, 0);
-
- testMenu = GetMenu(131);
- InsertMenu(testMenu, 0);
-
- DrawMenuBar();
- }
-
- //--------------------------------------------------------------------- DebugNum
-
- void DebugNum (long theNum)
- {
- Str255 tempStr;
-
- NumToString(theNum, tempStr);
- DebugStr(tempStr);
- }
-
- //-------------------------------------------------------------- PasStringCopy
-
- // Given a source string and storage for a second, this function…
- // copies from one to the other. It assumes Pascal style strings.
-
- void PasStringCopy (StringPtr p1, StringPtr p2)
- {
- register short stringLength;
-
- stringLength = *p2++ = *p1++;
- while (--stringLength >= 0)
- *p2++ = *p1++;
- }
-
- //-------------------------------------------------------------- PasStringConcat
- // This function concatenates the second Pascal string to the end of…
- // the first Pascal string.
-
- void PasStringConcat (StringPtr p1, StringPtr p2)
- {
- short wasLength, addedLength, i;
-
- wasLength = *p1;
- if (wasLength > 255)
- wasLength = 255;
-
- addedLength = *p2;
- if ((wasLength + addedLength) > 255)
- addedLength = 255 - wasLength;
-
- *p1 = wasLength + addedLength;
-
- *p1++;
- *p2++;
-
- for (i = 0; i < wasLength; i++)
- *p1++;
-
- for (i = 0; i < addedLength; i++)
- *p1++ = *p2++;
- }
-
- //--------------------------------------------------------------------- AllocateVennColorDiagramRegions
-
- void AllocateVennColorDiagramRegions (void)
- {
- #define kOvalDiameter 80
- #define kOvalLeft 52
- #define kOvalTop 260
- #define kCircleHOffset 23
- #define kCircleVOffset 40
- Rect tempOval, tempRect;
- RgnHandle tempR, tempG, tempB;
-
- wholeVenn = NewRgn();
- regionR = NewRgn();
- regionG = NewRgn();
- regionB = NewRgn();
- regionRG = NewRgn();
- regionGB = NewRgn();
- regionBR = NewRgn();
- regionRGB = NewRgn();
- tempR = NewRgn();
- tempG = NewRgn();
- tempB = NewRgn();
- blackRgn = NewRgn();
-
- if (!wholeVenn || !regionR || !regionG || !regionB || !regionRG || !blackRgn ||
- !regionGB || !regionBR || !regionRGB || !tempR || !tempG || !tempB)
- return;
-
- // Create RED circle.
- SetRect(&tempOval, 0, 0, kOvalDiameter, kOvalDiameter);
- OffsetRect(&tempOval, kOvalLeft, kOvalTop);
- OpenRgn();
- FrameOval(&tempOval);
- CloseRgn(regionR);
-
- // Create GREEN circle.
- SetRect(&tempOval, 0, 0, kOvalDiameter, kOvalDiameter);
- OffsetRect(&tempOval, kOvalLeft, kOvalTop);
- OffsetRect(&tempOval, -kCircleHOffset, kCircleVOffset);
- OpenRgn();
- FrameOval(&tempOval);
- CloseRgn(regionG);
-
- // Create BLUE circle.
- SetRect(&tempOval, 0, 0, kOvalDiameter, kOvalDiameter);
- OffsetRect(&tempOval, kOvalLeft, kOvalTop);
- OffsetRect(&tempOval, kCircleHOffset, kCircleVOffset);
- OpenRgn();
- FrameOval(&tempOval);
- CloseRgn(regionB);
-
- CopyRgn(regionR, tempR);
- CopyRgn(regionG, tempG);
- CopyRgn(regionB, tempB);
-
- // Create whole region.
- UnionRgn(regionR, regionG, wholeVenn);
- UnionRgn(wholeVenn, regionB, wholeVenn);
-
- // Create 2-color intersections.
- SectRgn(regionR, regionG, regionRG);
- DiffRgn(regionRG, regionB, regionRG);
-
- SectRgn(regionG, regionB, regionGB);
- DiffRgn(regionGB, regionR, regionGB);
-
- SectRgn(regionB, regionR, regionBR);
- DiffRgn(regionBR, regionG, regionBR);
-
- // Create 3-color intersection.
- SectRgn(regionR, regionG, regionRGB);
- SectRgn(regionRGB, regionB, regionRGB);
-
- // Finally, clip original R, G, and B regions.
- DiffRgn(regionR, tempG, regionR);
- DiffRgn(regionR, tempB, regionR);
-
- DiffRgn(regionG, tempR, regionG);
- DiffRgn(regionG, tempB, regionG);
-
- DiffRgn(regionB, tempG, regionB);
- DiffRgn(regionB, tempR, regionB);
-
- DisposeRgn(tempR);
- DisposeRgn(tempG);
- DisposeRgn(tempB);
-
- // Create black region.
- tempRect.left = 16;
- tempRect.top = 240;
- tempRect.right = tempRect.left + 154;
- tempRect.bottom = 400;
- RectRgn(blackRgn, &tempRect);
- DiffRgn(blackRgn, wholeVenn, blackRgn);
- }
-
- //--------------------------------------------------------------------- SetUpCMYKRects
-
- void SetUpCMYKRects (void)
- {
- #define kCMYKTop 50
- #define kCMYKBottom 80
- #define kCMYKWide 60
- #define kCLeft 311
- #define kMLeft kCLeft + kCMYKWide + 16
- #define kYLeft kMLeft + kCMYKWide + 16
- #define kKLeft kYLeft + kCMYKWide + 16
-
- SetRect(&rectC, kCLeft, kCMYKTop, kCLeft + kCMYKWide, kCMYKBottom);
- SetRect(&rectM, kMLeft, kCMYKTop, kMLeft + kCMYKWide, kCMYKBottom);
- SetRect(&rectY, kYLeft, kCMYKTop, kYLeft + kCMYKWide, kCMYKBottom);
- SetRect(&rectK, kKLeft, kCMYKTop, kKLeft + kCMYKWide, kCMYKBottom);
- }
-
- //--------------------------------------------------------------------- SetUpBounceLine
-
- void SetUpBounceLine (void)
- {
- Rect gWorldBounds;
- GDHandle wasWorld;
- CGrafPtr wasCPort;
- OSErr theErr;
-
- SetRect(&bounceRect, 0, 0, 581, 560);
- OffsetRect(&bounceRect, 76, 240);
-
- x1 = RandomInt(bounceRect.right - bounceRect.left) + bounceRect.left;
- x2 = RandomInt(bounceRect.right - bounceRect.left) + bounceRect.left;
-
- y1 = RandomInt(bounceRect.bottom - bounceRect.top) + bounceRect.top;
- y2 = RandomInt(bounceRect.bottom - bounceRect.top) + bounceRect.top;
-
- deltaX1 = RandomInt(10) + 6;
- deltaY1 = RandomInt(10) + 6;
- deltaX2 = RandomInt(10) + 6;
- deltaY2 = RandomInt(10) + 6;
-
- wasTicks = TickCount();
-
- // Create GWorld.
- gWorldBounds.left = bounceRect.left >> 2;
- gWorldBounds.top = bounceRect.top >> 2;
- gWorldBounds.right = (bounceRect.right >> 2) + kLineThick;
- gWorldBounds.bottom = (bounceRect.bottom >> 2) + kLineThick;
- OffsetRect(&gWorldBounds, -gWorldBounds.left, -gWorldBounds.top);
- GetGWorld(&wasCPort, &wasWorld);
- theErr = NewGWorld(&theGWorld, 32, &gWorldBounds, nil, nil, useTempMem);
- if (theErr != noErr)
- {
- theGWorld = 0L;
- goto bail;
- }
- LockPixels(GetGWorldPixMap(theGWorld));
- SetGWorld(theGWorld, 0L);
- ForeColor(blackColor);
- BackColor(whiteColor);
- PaintRect(&gWorldBounds);
- PenSize(kLineThick, kLineThick);
- UnlockPixels(GetGWorldPixMap(theGWorld));
- SetGWorld(wasCPort, wasWorld);
-
- bail:
-
- return;
- }
-
- //--------------------------------------------------------------------- PickerMatchColors
-
- void PickerMatchColors (PickerCWPtr cw, CMColor *myColors, unsigned long count)
- {
- CMError theErr;
-
- theErr = noErr;
-
- if (!cw->matchingNeeded)
- goto bail;
-
- if (cw->cw)
- {
- PickerMatchColorsSimple(myColors, count, cw->srcSpace, cw->srcProfSpace);
-
- theErr = CWMatchColors(cw->cw, myColors, count);
- if (theErr != noErr)
- goto bail;
-
- if (cw->cw2)
- {
- theErr = CWMatchColors(cw->cw2, myColors, count);
- if (theErr != noErr)
- goto bail;
- }
-
- PickerMatchColorsSimple(myColors, count, cw->dstProfSpace, cw->dstSpace);
- }
- else
- PickerMatchColorsSimple(myColors, count, cw->srcSpace, cw->dstSpace);
-
- bail:
-
- return;
- }
-
- //--------------------------------------------------------------------- PickerMatchColorsSimple
-
- void PickerMatchColorsSimple (CMColor *myColors, unsigned long count,
- OSType srcSpace, OSType dstSpace)
- {
- // Try to match it ourselves.
- CMColor *color;
-
- if ( srcSpace==dstSpace )
- return;
-
- if ( srcSpace==cmRGBData && dstSpace==cmCMYKData )
- {
- for ( color=myColors; count>0; count--, color++)
- {
- colorK = (0xFFFF - MAX3(colorR, colorG, colorB));
- colorC = (0xFFFF - colorR) - colorK;
- colorM = (0xFFFF - colorG) - colorK;
- colorY = (0xFFFF - colorB) - colorK;
- }
- }
- else if ( srcSpace==cmCMYKData && dstSpace==cmRGBData )
- {
- for ( color=myColors; count>0; count--, color++)
- {
- colorR = 0xFFFF - colorC;
- colorG = 0xFFFF - colorM;
- colorB = 0xFFFF - colorY;
-
- colorR = (colorR > colorK ) ? (colorR - colorK) : (0);
- colorG = (colorG > colorK ) ? (colorG - colorK) : (0);
- colorB = (colorB > colorK ) ? (colorB - colorK) : (0);
- }
- }
-
- return;
- }
-
- //--------------------------------------------------------------------- GetColorSyncVersion
-
- long GetColorSyncVersion (void)
- {
- long colorSyncLong;
-
- if ( Gestalt(gestaltColorMatchingVersion, &colorSyncLong)==noErr )
- return colorSyncLong;
- else
- return 0L;
- }
-
- //--------------------------------------------------------------------- GetProfileColorSpace
-
- OSType GetProfileColorSpace (CMProfileRef prof)
- {
- CMAppleProfileHeader header;
- OSType space;
- CMError theErr;
-
- space = cmRGBData;
-
- if (prof)
- {
- if (GetColorSyncVersion() >= gestaltColorSync20)
- {
- theErr = CMGetProfileHeader(prof, &header);
- if (theErr != noErr)
- goto bail;
-
- space = header.cm2.dataColorSpace;
- }
- }
-
- bail:
-
- return space;
- }
-
- //--------------------------------------------------------------------- PickerNewColorWorld
-
- OSErr NPickerNewColorWorld (PickerCWPtr cw, CMProfileRef src, CMProfileRef prf,
- CMProfileRef dst, OSType srcSpace, OSType dstSpace)
- {
- CMError theErr;
- CMProfileRef systemProfile;
- CMAppleProfileHeader header;
- Boolean srcHeaderWasChanged;
- long csVersion;
-
- theErr = noErr;
- systemProfile = nil;
- cw->cw = nil;
- cw->cw2 = nil;
- cw->matchingNeeded = !(srcSpace == dstSpace);
-
- // Remember the spaces.
- cw->srcSpace = (srcSpace)?(srcSpace):(cmRGBData);
- cw->dstSpace = (dstSpace)?(dstSpace):(cmRGBData);
- cw->srcProfSpace = cw->srcSpace;
- cw->dstProfSpace = cw->dstSpace;
- cw->prfProfSpace = GetProfileColorSpace(prf);
-
- // First make sure that ColorSync2 is around.
- csVersion = GetColorSyncVersion() ;
- if (csVersion < gestaltColorSync20)
- {
- theErr = colorSyncNotInstalled;
- if (theErr == noErr)
- goto bail;
- }
-
- // if no-op match, bail
- if (src==0L && prf==0L && dst==0L)
- goto bail;
-
- // Derive from system prof
- if (dst == 0L)
- {
- if (!systemProfile)
- (void) CMGetSystemProfile(&systemProfile) ;
- dst = systemProfile;
- cw->dstProfSpace = cmRGBData;
- cw->matchingNeeded = true;
- }
- if (src == 0L)
- {
- if (!systemProfile)
- (void) CMGetSystemProfile(&systemProfile) ;
- src = systemProfile;
- cw->srcProfSpace = cmRGBData;
- cw->matchingNeeded = true;
- }
-
- // Set the noGamut-bit
- if ( src && csVersion > gestaltColorSync20)
- {
- if (CMGetProfileHeader(src, &header) == noErr)
- {
- header.cm2.flags &= cmGamutCheckingMask;
- (void) CMSetProfileHeader(src, &header);
- srcHeaderWasChanged = true;
- }
- }
-
- // Use ColorSync to make the color world.
- if (prf == 0L)
- {
- theErr = NCWNewColorWorld(&(cw->cw), src, dst);
- if (theErr == noErr)
- goto bail;
-
- cw->matchingNeeded = true;
- }
- else
- {
- CMConcatProfileSet3 concat;
-
- concat.keyIndex = 1;
- concat.count = 3;
- concat.profileSet[0]= src;
- concat.profileSet[1]= prf;
- concat.profileSet[2]= dst;
-
- theErr = CWConcatColorWorld(&(cw->cw), (CMConcatProfileSet*)&concat);
-
- // the above will generate an error
- // if any one of the profiles is a 1.0 profile
- if (theErr)
- {
- theErr = NCWNewColorWorld(&(cw->cw), src, prf);
- if (theErr == noErr)
- goto bail;
-
- theErr = NCWNewColorWorld(&(cw->cw2), prf, dst);
- if (theErr == noErr)
- goto bail;
- }
-
- if (systemProfile)
- (void) CMCloseProfile(systemProfile);
-
- cw->matchingNeeded = true;
- }
-
- bail:
- // Us-set the noGamut-bit
- if ( srcHeaderWasChanged && src!=systemProfile )
- {
- header.cm2.flags -= cmGamutCheckingMask;
- (void) CMSetProfileHeader(src, &header);
- }
-
- // Dispose of derived profiles
- if (systemProfile) (void) CMCloseProfile(systemProfile);
-
- if (theErr)
- PickerDisposeColorWorld(cw);
-
- return theErr;
- }
-
- //--------------------------------------------------------------------- PickerDisposeColorWorld
-
- void PickerDisposeColorWorld (PickerCWPtr cw)
- {
- if (cw->cw)
- CWDisposeColorWorld(cw->cw);
-
- if (cw->cw2)
- CWDisposeColorWorld(cw->cw2);
-
- cw->cw = 0;
- cw->cw2 = 0;
- cw->srcSpace = cw->dstSpace = 0L;
- cw->srcProfSpace = cw->prfProfSpace = cw->dstProfSpace = 0L;
- cw->matchingNeeded = false;
- }
-
- //--------------------------------------------------------------------- OpenProfileHandle
-
- CMError OpenProfileHandle (CMProfileRef *profReference, Handle profHandle,
- UInt32 flags, UInt32 intent)
- {
- CMProfileLocation profLocation;
-
- profLocation.locType = cmHandleBasedProfile;
- profLocation.u.handleLoc.h = profHandle;
-
- (**(CM2Header **)profHandle).flags = flags;
- (**(CM2Header **)profHandle).renderingIntent = intent;
-
- return CMOpenProfile(profReference, &profLocation);
- }
-
-